/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/


/**
 * @file
 * @brief Interface for report errors.
 *
 * @author  WXQ#XDU
 * @date    2024.11
 */

#pragma once

#ifndef AMCC_ERROR_H
#define AMCC_ERROR_H

#include "amcc_config.h"

AMCC_DECL_BEGIN


/**
 * @brief Error codes defined by AMCC
 */
typedef enum error_code {
    #define  ERRCODE_DEFN(N, ENUM, DESC)   ENUM=N
    #define  ERRCODE_DEF( N, ENUM, DESC)   ENUM

    #include "../meta/_errname_desc.inc"

    #undef   ERRCODE_DEFN
    #undef   ERRCODE_DEF
} EnumErrorCode;


/**
 * @brief Get the description of current 'errno' of standard C.
 * 
 * @return The description of current 'errno'.
 */
extern const char* error_errno_desc();

/**
 * @brief  Get the count of errors.
 * @return  The count of errors during compiling input file.
 */
extern int error_get_count() ;


//
// some convenient, shorter API
//

/**
 * @brief Report a AMCC bug.
 * @param fmt    format string
 * @param ...    other parameters for format string
 */
#define ERROR_REPORT_BUG(fmt, ...)    do {                  \
            char tmpbuff[300];                              \
            sprintf(tmpbuff, fmt, ## __VA_ARGS__ );         \
            error_report_system_impl(__FILE__,  __LINE__,   \
                EC_BUG, __FILE__,  __LINE__, tmpbuff );     \
        } while(0)

/**
* @brief Report a memory allocation failure.
*/
#define ERROR_REPORT_MALLOC()     error_report_system_impl( \
                __FILE__,  __LINE__, EC_ALLOC, __FUNCTION__ )

/**
 * @brief Report a file operation failure such as create/open, read, write.
 * @param ec      error code
 * @param fpath   file path of error
 */
#define ERROR_REPORT_FILEOP(ec, fpath)  error_report_fileop_impl( \
                __FILE__,  __LINE__, fpath, ec, error_errno_desc())

/**
 * @brief Report an error of a system operation.
 *
 * @param ec    error code
 * @param ...   other parameters for format string
 *
 * @see 'error_formats[]' in file 'error.c'
 */
#define ERROR_REPORT_SYSTEM(ec, ...)    error_report_system_impl( \
                __FILE__,  __LINE__, ec, ## __VA_ARGS__ )

/**
 * @brief Reports an error in an input file
 *
 * @param fpath  input file name of error
 * @param line   line number of error
 * @param col    column number of error
 * @param ec     error code
 * @param ...    other parameters for format string
 *
 * @see 'error_formats[]' in srcfile 'error.c'
 */
#define ERROR_REPORT_INPUT(fpath, line, col, ec, ...) error_report_input_impl(\
        __FILE__,  __LINE__, fpath, line,col, ec, ## __VA_ARGS__ )



// Implementation for API ERROR_REPORT_*(),
// Your best choice is call ERROR_REPORT_*().

extern void error_report_input_impl(
                const char* srcFile, int srcLine,
                const char* inputFileName,
                int line, int col, EnumErrorCode ecode, ...);
extern void error_report_fileop_impl(
                const char* srcFile, int srcLine,
                const char* fileName, EnumErrorCode ecode, ...);
extern void error_report_system_impl(
                const char* srcFile, int srcLine,
                EnumErrorCode ecode, ...);


AMCC_DECL_END

#endif // #ifndef AMCC_ERROR_H
